MMIS Prototype
众所周知,比较古老的圆角的做法是通过表格和图像构成。但随着AJAX的流行、CSS + DIV的页面布局技术的风靡,古老的做法显得苍白无力,所以人们不断寻求改进的方法。本文的实现就是一种现在比较流行的做法。
实现原理
其实这种方法的原理很简单——在要圆角的元素的上下堆放一些边缘(MARGIN)不同的<DIV>元素(也有的使用其它元素的,如<B>等,不过原理是一样的),如下图所示:
清单1 原理图
接下来的问题就是计算margin的长度。这也不难只要运用一下初中所学的勾股定理便可以求出来,如下图所示:
清单2 MARGIN求解图
具体编码
下面该工具类的源码:
var
Corner
=
{
//
标志圆角位置的旗标
TOP_LEFT:
0x1
,
TOP_RIGHT:
0x2
,
BOTTOM_LEFT:
0x4
,
BOTTOM_RIGHT:
0x8
,
ALL:
0xf
,
/**/
/*
*******************************************************
* target: 要圆角的目标元素
* radius: 圆角的半径,默认值为5
* flags: 圆角位置的旗标或其组合,默认值为全部
* backgroundColor: 圆角的背景色,默认值为目标元素的背景色
*******************************************************
*/
round:
function
(target,
radius, flags, backgroundColor)
{
var
t
=
$(target);
var
r
=
radius
||
5
;
var
f
=
flags
||
Corner.ALL;
var
c
=
Element.getStyle(t,
'backgroundColor');
var
b
=
backgroundColor
||
c;
//
修正在IE里元素样式为FLOAT时,圆角DIV宽度为0的BUG
var
ft
=
Element.getStyle(t, '
float
');
if
(navigator.appVersion.match(
/
\bMSIE\b
/
)
&&
ft
!=
'none'
&&
!
t.style.width)
{
Element.setStyle(t,
{ width: Element.getWidth(t)
+
'px' }
);
}
//
创建DIV,并把目标元素的内容剪切到其中
var
d
=
document.createElement('div');
d.innerHTML
=
t.innerHTML;
t.innerHTML
=
'';
//
设置新DIV的背景色为目标元素的背景色,并目标元素为透明背景
Element.setStyle(
d,
{ backgroundColor: c }
);
Element.setStyle( t,
{ backgroundColor: 'transparent' }
);
//
设置新DIV的高度为目标元素的高度
var
h
=
t.style.height;
var
nh
=
0
;
if
(h)
{
Element.setStyle( d,
{ height: h }
);
nh
=
parseInt(h);
}
//
设置新DIV的缩进
var
p
=
Element.getStyle(t, 'padding');
if
(p)
{
Element.setStyle( d,
{ padding: p }
);
Element.setStyle( t,
{ padding: '0px 0px 0px 0px' }
);
}
//
创建用于新DIV和圆角DIV的文档片段,这样避免每次设置元素样式或添加新元素时重绘页面,提高效率
var
ds
=
document.createDocumentFragment();
var
ls
=
null
;
//
创建顶部圆角DIV
if
(f
&
(Corner.TOP_LEFT
|
Corner.TOP_RIGHT))
{
ls
=
Corner._createRoundFragment(r, f, b ,
false
);
ds.appendChild(ls);
nh
+=
r;
}
ds.appendChild(d);
//
创建底部圆角DIV
if
(f
&
(Corner.BOTTOM_LEFT
|
Corner.BOTTOM_RIGHT))
{
ls
=
Corner._createRoundFragment(r, f, b,
true
);
ds.appendChild(ls);
nh
+=
r;
}
if
(h)
{
Element.setStyle( t,
{ height: nh
+
'px' }
);
}
t.appendChild(ds);
}
,
_createRoundFragment:
function
(r, f, c, b)
{
var
ls
=
document.createDocumentFragment();
var
l
=
null
;
var
m
=
ml
=
mr
=
null
;
var
j
=
0
;
for
(i
=
1
; i
<=
r; i
++
)
{
l
=
document.createElement('div');
//
计算margin
j
=
b
?
i : r
-
i
+
1
;
m
=
Math.sqrt(r
*
r
-
j
*
j);
m
=
Math.round(r
-
m)
+
'px';
if
(b)
{
ml
=
f
&
Corner.BOTTOM_LEFT
?
m : '0px';
mr
=
f
&
Corner.BOTTOM_RIGHT
?
m : '0px';
}
else
{
ml
=
f
&
Corner.TOP_LEFT
?
m : '0px';
mr
=
f
&
Corner.TOP_RIGHT
?
m : '0px';
}
Element.setStyle( l,
{ backgroundColor: c,
fontSize: '1px',
height: '1px',
marginLeft: ml,
marginRight: mr,
overflowX: 'hidden',
overflowY: 'hidden' }
);
ls.appendChild(l);
}
return
ls;
}
}
清单3 实现代码
因为Javascript是没有方法重写的,所以当你调用Corner.round('div1')和调用Coner.round('div1', 20)是一样的,它们最终调用的都是Corner.round(target, radius, flags, backgroundColor),只过没有赋值的参数会为undefined。这里有一个小技巧,就var
r = radius || 5,这里的“||”符号表示如果radius为undefined、null或0等值时,r的取值为5。
接着让我们看看运行的页面代码:
<!
DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
<
head
>
<
title
>
RounderCorner Prototype
</
title
>
<
script
type
="text/javascript"
src
="scripts/prototype-1.5.0.js"
></
script
>
<
script
type
="text/javascript"
src
="scripts/Corner.js"
></
script
>
<
script
type
="text/javascript"
>
//
<![CDATA[
Event.observe(window,
'load', init,
false
);
function
init() {
Corner.round('div1');
Corner.round('div2',
20
, Corner.TOP_LEFT
|
Corner.BOTTOM_RIGHT);
Corner.round('div3',
20
,
Corner.ALL, 'Red');
}
//
]]>
</
script
>
</
head
>
<
body
>
<
div
id
="div1"
style
="width: 318px; height:
103px; background-color: #ffcccc"
>
Corner.round('div1');
</
div
>
<
br
/>
<
div
id
="div2"
style
="width: 317px; height:
100px; background-color: #cccccc"
>
Corner.round('div2', 20, Corner.TOP_LEFT | Corner.BOTTOM_RIGHT);
</
div
>
<
br
/>
<
div
id
="div3"
style
="width: 315px; height:
100px; background-color: #ccffcc"
>
Corner.round('div3', 20, Corner.ALL, 'Red');
</
div
>
</
body
>
</
html
>
清单4 测试代码
上述代码很简单明了,相信大家都明白。下面看一下运行截图吧。
清单5 运行截图
总结
以上代码只作抛砖引玉之用,所以还有很多功能没有实现。
posted on 2007-03-23 01:37
Max 阅读(6535)
评论(12) 编辑 收藏 所属分类:
方法与技巧(Tips & tricks)